load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_license//rules:license.bzl", "license")

package(default_applicable_licenses = [":license"])

license(
    name = "license",
    license_kinds = ["@rules_license//licenses/spdx:Apache-2.0"],
    license_text = "LICENSE",
)

cc_library(
    name = "acceptor",
    srcs = glob(["wangle/acceptor/*.cpp"]),
    hdrs = glob(["wangle/acceptor/*.h"]),
    includes = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":ssl",
        "@fizz",
        "@fmt",
        "@folly//folly:constexpr_math",
        "@folly//folly:conv",
        "@folly//folly:exception_wrapper",
        "@folly//folly:format",
        "@folly//folly:glog",
        "@folly//folly:intrusive_list",
        "@folly//folly:memory",
        "@folly//folly:network_address",
        "@folly//folly:optional",
        "@folly//folly:random",
        "@folly//folly:range",
        "@folly//folly:string",
        "@folly//folly/experimental/io:async_io_uring_socket",
        "@folly//folly/io:socket_option_map",
        "@folly//folly/io/async:async_base",
        "@folly//folly/io/async:async_socket",
        "@folly//folly/io/async:async_ssl_socket",
        "@folly//folly/io/async:async_transport",
        "@folly//folly/io/async:async_udp_server_socket",
        "@folly//folly/io/async:delayed_destruction",
        "@folly//folly/io/async:server_socket",
        "@folly//folly/io/async:ssl_context",
        "@folly//folly/io/async/fdsock:async_fd_socket",
        "@folly//folly/portability:openssl",
        "@folly//folly/portability:sockets",
        "@folly//folly/portability:unistd",
        "@glog",
    ],
)

cc_library(
    name = "bootstrap",
    srcs = glob(["wangle/bootstrap/*.cpp"]),
    hdrs = glob(
        ["wangle/bootstrap/*.h"],
        exclude = ["wangle/bootstrap/*-inl.h"],
    ),
    includes = ["."],
    textual_hdrs = glob(["wangle/bootstrap/*-inl.h"]),
    visibility = ["//visibility:public"],
    deps = [
        ":acceptor",
        ":channel",
        ":ssl",
        "@folly//folly:exception_wrapper",
        "@folly//folly:network_address",
        "@folly//folly:shared_mutex",
        "@folly//folly/executors:io_thread_pool_executor",
        "@folly//folly/executors/thread_factory",
        "@folly//folly/futures:core",
        "@folly//folly/io:socket_option_map",
        "@folly//folly/io/async:async_socket",
        "@folly//folly/io/async:async_ssl_socket",
        "@folly//folly/io/async:async_transport",
        "@folly//folly/io/async:async_udp_server_socket",
        "@folly//folly/io/async:destructor_check",
        "@folly//folly/io/async:event_base_manager",
        "@folly//folly/io/async:server_socket",
        "@folly//folly/ssl:ssl_session",
        "@folly//folly/synchronization:baton",
    ],
)

cc_library(
    name = "channel",
    srcs = glob(["wangle/channel/*.cpp"]),
    hdrs = glob(
        ["wangle/channel/*.h"],
        exclude = ["wangle/channel/*-inl.h"],
    ),
    includes = ["."],
    textual_hdrs = glob(["wangle/channel/*-inl.h"]),
    visibility = ["//visibility:public"],
    deps = [
        ":acceptor",
        "@folly//folly:exception_wrapper",
        "@folly//folly:format",
        "@folly//folly:memory",
        "@folly//folly:optional",
        "@folly//folly:singleton",
        "@folly//folly:unit",
        "@folly//folly/executors:io_thread_pool_executor",
        "@folly//folly/futures:core",
        "@folly//folly/futures:shared_promise",
        "@folly//folly/io:iobuf",
        "@folly//folly/io/async:async_base",
        "@folly//folly/io/async:async_socket",
        "@folly//folly/io/async:async_transport",
        "@folly//folly/io/async:async_udp_server_socket",
        "@folly//folly/io/async:delayed_destruction",
        "@folly//folly/io/async:event_base_manager",
        "@folly//folly/io/async:request_context",
        "@glog",
    ],
)

cc_library(
    name = "channel_broadcast",
    hdrs = glob(
        ["wangle/channel/broadcast/*.h"],
        exclude = ["wangle/channel/broadcast/*-inl.h"],
    ),
    includes = ["."],
    textual_hdrs = glob(["wangle/channel/broadcast/*-inl.h"]),
    visibility = ["//visibility:public"],
    deps = [
        ":bootstrap",
        ":channel",
        "@folly//folly:exception_wrapper",
        "@folly//folly:thread_local",
        "@folly//folly/futures:shared_promise",
        "@folly//folly/io/async:delayed_destruction",
    ],
)

cc_library(
    name = "client_persistence",
    srcs = glob(["wangle/client/persistence/*.cpp"]),
    hdrs = glob(
        ["wangle/client/persistence/*.h"],
        exclude = ["wangle/client/persistence/*-inl.h"],
    ),
    includes = ["."],
    textual_hdrs = glob(["wangle/client/persistence/*-inl.h"]),
    visibility = ["//visibility:public"],
    deps = [
        "@folly//folly:executor",
        "@folly//folly:file_util",
        "@folly//folly:likely",
        "@folly//folly:memory",
        "@folly//folly:optional",
        "@folly//folly:scope_guard",
        "@folly//folly/container:evicting_cache_map",
        "@folly//folly/json:dynamic",
        "@folly//folly/portability:sys_time",
        "@folly//folly/portability:unistd",
        "@folly//folly/synchronization:lock",
        "@folly//folly/synchronization:saturating_semaphore",
        "@folly//folly/system:thread_name",
    ],
)

cc_library(
    name = "client_ssl",
    srcs = glob(["wangle/client/ssl/*.cpp"]),
    hdrs = glob(
        ["wangle/client/ssl/*.h"],
        exclude = ["wangle/client/ssl/*-inl.h"],
    ),
    includes = ["."],
    textual_hdrs = glob(["wangle/client/ssl/*-inl.h"]),
    visibility = ["//visibility:public"],
    deps = [
        ":client_persistence",
        ":ssl",
        "@folly//folly:executor",
        "@folly//folly:fbstring",
        "@folly//folly:memory",
        "@folly//folly:optional",
        "@folly//folly:shared_mutex",
        "@folly//folly/io:iobuf",
        "@folly//folly/io/async:async_ssl_socket",
        "@folly//folly/io/async:ssl_context",
        "@folly//folly/json:dynamic",
        "@folly//folly/portability:openssl",
        "@folly//folly/ssl:openssl_ptr_types",
        "@openssl//:ssl",
    ],
)

cc_library(
    name = "codec",
    srcs = glob(["wangle/codec/*.cpp"]),
    hdrs = glob(["wangle/codec/*.h"]),
    includes = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":channel",
        "@folly//folly/io:iobuf",
    ],
)

cc_library(
    name = "service",
    hdrs = glob(["wangle/service/*.h"]),
    includes = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":bootstrap",
        ":channel",
        "@folly//folly:memory",
        "@folly//folly/futures:core",
    ],
)

cc_library(
    name = "ssl",
    srcs = glob(["wangle/ssl/*.cpp"]),
    # NOTE: Add the SSLContextSelectionMisc.h header here directly here to avoid circular deps.
    hdrs = glob(["wangle/ssl/*.h"]) + ["wangle/acceptor/SSLContextSelectionMisc.h"],
    includes = ["."],
    visibility = ["//visibility:public"],
    deps = [
        ":util",
        "@folly//folly:conv",
        "@folly//folly:file_util",
        "@folly//folly:format",
        "@folly//folly:glog",
        "@folly//folly:memory",
        "@folly//folly:optional",
        "@folly//folly:random",
        "@folly//folly:scope_guard",
        "@folly//folly:shared_mutex",
        "@folly//folly:string",
        "@folly//folly:synchronized",
        "@folly//folly/container:evicting_cache_map",
        "@folly//folly/executors:function_scheduler",
        "@folly//folly/fibers:core_manager",
        "@folly//folly/futures:core",
        "@folly//folly/hash",
        "@folly//folly/io/async:async_base",
        "@folly//folly/io/async:async_ssl_socket",
        "@folly//folly/io/async:password_in_file",
        "@folly//folly/io/async:ssl_context",
        "@folly//folly/io/async:ssl_options",
        "@folly//folly/json:dynamic",
        "@folly//folly/portability:gflags",
        "@folly//folly/portability:openssl",
        "@folly//folly/ssl:openssl_cert_utils",
        "@folly//folly/ssl:openssl_ptr_types",
        "@folly//folly/ssl:openssl_ticket_handler",
        "@folly//folly/ssl:password_collector",
        "@glog",
        "@openssl//:ssl",
    ],
)

cc_library(
    name = "util",
    srcs = glob(["wangle/util/*.cpp"]),
    hdrs = glob(["wangle/util/*.h"]),
    includes = ["."],
    visibility = ["//visibility:public"],
    deps = [
        "@folly//folly:conv",
        "@folly//folly:file_util",
        "@folly//folly:function",
        "@folly//folly:memory",
        "@folly//folly:shared_mutex",
        "@folly//folly:singleton",
        "@folly//folly:string",
        "@folly//folly:thread_local",
        "@folly//folly/executors:function_scheduler",
        "@folly//folly/io/async:async_base",
        "@folly//folly/io/async:scoped_event_base_thread",
    ],
)

# ==================================================================================================
# Tests
# ==================================================================================================
cc_library(
    name = "test_main",
    srcs = ["wangle/test/TestMain.cpp"],
    visibility = ["//visibility:public"],
    deps = [
        "@folly//folly/init",
        "@folly//folly/portability:gtest",
    ],
)

cc_library(
    name = "acceptor_test_lib",
    hdrs = ["wangle/acceptor/test/AcceptorHelperMocks.h"],
    visibility = ["//visibility:public"],
    deps = [
        ":acceptor",
        "@folly//folly/portability:gmock",
        "@folly//folly/portability:gtest",
    ],
)

[cc_test(
    name = test_file.removesuffix(".cpp").replace("/", "_"),
    size = "small",
    srcs = [test_file],
    deps = [
        ":acceptor",
        ":acceptor_test_lib",
        ":test_main",
        "@folly//folly:file_util",
        "@folly//folly:network_address",
        "@folly//folly/futures:barrier",
        "@folly//folly/io/async:async_base",
        "@folly//folly/io/async:scoped_event_base_thread",
        "@folly//folly/io/async/test:async_ssl_socket_test_lib",
        "@folly//folly/io/async/test:mocks",
        "@folly//folly/portability:gflags",
        "@folly//folly/portability:gmock",
        "@folly//folly/portability:gtest",
        "@folly//folly/portability:unistd",
        "@folly//folly/synchronization:baton",
        "@folly//folly/testing:test_util",
    ],
) for test_file in glob(["wangle/acceptor/test/*Test.cpp"])]

# This test is flaky.
BOOTSTRAP_DISABLED_TESTS = [
    "wangle/bootstrap/test/AcceptRoutingHandlerTest.cpp",
]

cc_library(
    name = "bootstrap_test_lib",
    hdrs = ["wangle/bootstrap/test/Mocks.h"],
    visibility = ["//visibility:public"],
    deps = [
        ":bootstrap",
        ":channel",
        ":channel_test_lib",
        "@folly//folly/portability:gmock",
        "@folly//folly/portability:gtest",
    ],
)

[
    cc_test(
        name = test_file.removesuffix(".cpp").replace("/", "_"),
        size = "small",
        srcs = [test_file],
        deps = [
            ":bootstrap",
            ":bootstrap_test_lib",
            ":channel",
            ":test_main",
            "@folly//folly/portability:gtest",
            "@folly//folly/synchronization:latch",
            "@folly//folly/testing:test_util",
            "@glog",
        ],
    )
    for test_file in glob(["wangle/bootstrap/test/*Test.cpp"])
    if test_file not in BOOTSTRAP_DISABLED_TESTS
]

cc_library(
    name = "channel_test_lib",
    hdrs = [
        "wangle/channel/test/MockHandler.h",
        "wangle/channel/test/MockPipeline.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":channel",
        "@folly//folly:move_wrapper",
        "@folly//folly/portability:gmock",
    ],
)

[cc_test(
    name = test_file.removesuffix(".cpp").replace("/", "_"),
    size = "small",
    srcs = [test_file],
    deps = [
        ":channel",
        ":channel_test_lib",
        ":test_main",
        "@boost.thread",
        "@folly//folly/io/async:async_socket",
        "@folly//folly/io/async/test:async_socket_test_lib",
        "@folly//folly/portability:gmock",
        "@folly//folly/portability:gtest",
    ],
) for test_file in glob(["wangle/channel/test/*Test.cpp"])]

cc_library(
    name = "channel_broadcast_test_lib",
    hdrs = ["wangle/channel/broadcast/test/Mocks.h"],
    visibility = ["//visibility:public"],
    deps = [
        ":channel_broadcast",
        ":codec",
        "@folly//folly:move_wrapper",
        "@folly//folly/portability:gmock",
        "@folly//folly/portability:gtest",
    ],
)

[cc_test(
    name = test_file.removesuffix(".cpp").replace("/", "_"),
    size = "small",
    srcs = [test_file],
    deps = [
        ":bootstrap",
        ":channel",
        ":channel_broadcast",
        ":channel_broadcast_test_lib",
        ":channel_test_lib",
        ":codec",
        ":test_main",
        "@folly//folly/portability:gtest",
        "@glog",
    ],
) for test_file in glob(["wangle/channel/broadcast/test/*Test.cpp"])]

cc_library(
    name = "client_persistence_test_lib",
    srcs = ["wangle/client/persistence/test/TestUtil.cpp"],
    hdrs = [
        "wangle/client/persistence/test/Mocks.h",
        "wangle/client/persistence/test/TestUtil.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":client_persistence",
        "@folly//folly:memory",
        "@folly//folly:optional",
        "@folly//folly/portability:gmock",
        "@folly//folly/portability:gtest",
        "@folly//folly/portability:unistd",
        "@folly//folly/testing:test_util",
    ],
)

# This test fails on some platforms.
CLIENT_PERSISTENCE_DISABLED_TESTS = [
    "wangle/client/persistence/test/LRUPersistentCacheTest.cpp",
]

[
    cc_test(
        name = test_file.removesuffix(".cpp").replace("/", "_"),
        size = "small",
        srcs = [test_file],
        deps = [
            ":client_persistence",
            ":client_persistence_test_lib",
            ":test_main",
            "@folly//folly:memory",
            "@folly//folly/executors:manual_executor",
            "@folly//folly/futures:barrier",
            "@folly//folly/futures:core",
            "@folly//folly/portability:gmock",
            "@folly//folly/portability:gtest",
            "@folly//folly/portability:unistd",
            "@folly//folly/synchronization:baton",
        ],
    )
    for test_file in glob(["wangle/client/persistence/test/*Test.cpp"])
    if test_file not in CLIENT_PERSISTENCE_DISABLED_TESTS
]

cc_library(
    name = "client_ssl_test_lib",
    srcs = ["wangle/client/ssl/test/TestUtil.cpp"],
    hdrs = [
        "wangle/client/ssl/test/Mocks.h",
        "wangle/client/ssl/test/TestUtil.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":client_ssl",
        "@folly//folly/portability:gmock",
        "@folly//folly/ssl:openssl_ptr_types",
        "@glog",
    ],
)

# These tests fail because openssl i2d_SSL_SESSION() seems to be returning different data
# from the data that is hard-coded / expected in the tests. Disable for now.
CLIENT_SSL_DISABLED_TESTS = [
    "wangle/client/ssl/test/SSLSessionCacheDataTest.cpp",
    "wangle/client/ssl/test/SSLSessionPersistentCacheTest.cpp",
    "wangle/client/ssl/test/ThreadSafeSSLSessionCacheTest.cpp",
]

[
    cc_test(
        name = test_file.removesuffix(".cpp").replace("/", "_"),
        size = "small",
        srcs = [test_file],
        deps = [
            ":client_persistence",
            ":client_persistence_test_lib",
            ":client_ssl",
            ":client_ssl_test_lib",
            ":ssl",
            ":test_main",
            "@folly//folly:conv",
            "@folly//folly:format",
            "@folly//folly:memory",
            "@folly//folly/io/async:ssl_context",
            "@folly//folly/json:dynamic",
            "@folly//folly/portability:gmock",
            "@folly//folly/portability:gtest",
            "@folly//folly/ssl:openssl_ptr_types",
        ],
    )
    for test_file in glob(["wangle/client/ssl/test/*Test.cpp"])
    if test_file not in CLIENT_SSL_DISABLED_TESTS
]

cc_test(
    name = "wangle_codec_test_CodecTest",
    size = "small",
    srcs = [
        "wangle/codec/test/CodecTest.cpp",
        "wangle/codec/test/CodecTestUtils.h",
    ],
    deps = [
        ":channel",
        ":codec",
        ":test_main",
        "@folly//folly:function",
        "@folly//folly/io:iobuf",
        "@folly//folly/portability:gtest",
    ],
)

cc_test(
    name = "wangle_service_test_ServiceTest",
    size = "small",
    srcs = ["wangle/service/test/ServiceTest.cpp"],
    deps = [
        ":codec",
        ":service",
        ":test_main",
        "@folly//folly/portability:gtest",
    ],
)

cc_library(
    name = "ssl_test_lib",
    hdrs = [
        "wangle/ssl/test/MockSSLStats.h",
        "wangle/ssl/test/TicketUtil.h",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":ssl",
        "@folly//folly:range",
        "@folly//folly/container:array",
        "@folly//folly/portability:gmock",
    ],
)

SSL_MEDIUM_SIZE_TESTS = [
    "wangle/ssl/test/TLSCredProcessorTest.cpp",
]

[cc_test(
    name = test_file.removesuffix(".cpp").replace("/", "_"),
    size = "medium" if test_file in SSL_MEDIUM_SIZE_TESTS else "small",
    srcs = [test_file],
    data = [
        "@folly//folly/io/async/test/certs:ca-cert.pem",
        "@folly//folly/io/async/test/certs:tests-cert.pem",
        "@folly//folly/io/async/test/certs:tests-key.pem",
    ],
    defines = ["WANGLE_USE_FOLLY_TESTUTIL"],
    deps = [
        ":acceptor",
        ":ssl",
        ":ssl_test_lib",
        ":test_main",
        "@folly//folly:file",
        "@folly//folly:file_util",
        "@folly//folly:random",
        "@folly//folly/io/async:async_base",
        "@folly//folly/io/async:async_socket",
        "@folly//folly/io/async:async_ssl_socket",
        "@folly//folly/io/async:ssl_context",
        "@folly//folly/io/async/test:async_ssl_socket_test_lib",
        "@folly//folly/io/async/test:test_ssl_server",
        "@folly//folly/portability:gflags",
        "@folly//folly/portability:gtest",
        "@folly//folly/portability:stdlib",
        "@folly//folly/portability:unistd",
        "@folly//folly/ssl:ssl_session",
        "@folly//folly/synchronization:baton",
        "@folly//folly/testing:test_util",
        "@glog",
    ],
) for test_file in glob(
    ["wangle/ssl/test/*Test.cpp"],
    # This is an integration test binary not meant to be run as a unit test.
    exclude = ["wangle/ssl/test/SSLCacheTest.cpp"],
)]

[cc_test(
    name = test_file.removesuffix(".cpp").replace("/", "_"),
    size = "small",
    srcs = [test_file],
    deps = [
        ":test_main",
        ":util",
        "@folly//folly:file",
        "@folly//folly:file_util",
        "@folly//folly:map_util",
        "@folly//folly:singleton",
        "@folly//folly:string",
        "@folly//folly/futures:core",
        "@folly//folly/portability:gtest",
        "@folly//folly/portability:sys_stat",
        "@folly//folly/synchronization:baton",
        "@folly//folly/synchronization:saturating_semaphore",
        "@folly//folly/testing:test_util",
        "@glog",
    ],
) for test_file in glob(["wangle/util/test/*Test.cpp"])]
